package br.com.sovi.gwt.client.controleunitario.infowindow;

import br.com.sovi.gwt.client.controleunitario.ControleUnitarioMarker;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.maps.client.InfoWindow;
import com.google.gwt.maps.client.InfoWindowContent;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.geocode.Geocoder;
import com.google.gwt.maps.client.geocode.LocationCallback;
import com.google.gwt.maps.client.geocode.Placemark;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class ControleUnitarioInfoWindow {

	private final MapWidget map;

	private InfoWindow infoWindow;

	private ControleUnitarioInfoWindowListener listener;

	private Label geoCodeLabel;

	public ControleUnitarioInfoWindow(MapWidget map) {
		this.map = map;
		infoWindow = map.getInfoWindow();
		geoCodeLabel = new Label();
		geoCodeLabel.setStyleName("cuiw_geoCodeLabel");
	}

	public ControleUnitarioInfoWindow(MapWidget map, ControleUnitarioInfoWindowListener listener) {
		this(map);
		this.listener = listener;
	}

	public void showInfoWindow(ControleUnitarioMarker marker) {
		infoWindow.close();

		InfoWindowContent content = new InfoWindowContent(buildContent(marker));

		infoWindow.open(marker.getLatLng(), content);

		map.setInfoWindowEnabled(true);
	}

	private Widget buildContent(ControleUnitarioMarker marker) {
		VerticalPanel mainPanel = new VerticalPanel();

		{ // Pontos para mover para próximo ponto e anterior.
			HorizontalPanel pontosPanel = new HorizontalPanel();

			ControleUnitarioMarker next = listener.getNextMarker(marker);
			ControleUnitarioMarker previous = listener.getPreviousMarker(marker);
			
			if (previous != null) {
				pontosPanel.add(new Button("Anterior", new ChangePontoClickHandler(previous)));
			}

			if (next != null) {
				pontosPanel.add(new Button("Próximo", new ChangePontoClickHandler(next)));
			}

			mainPanel.add(pontosPanel);
		}

		{ // TODO ver GEOCODING
			if (marker.getJsArray() == null) {
				searchGeoCode(marker);
			}
			else {
				fillGeoCode(marker.getJsArray().get(0).getAddress());
			}
			mainPanel.add(geoCodeLabel);
		}

		return mainPanel;
	}

	private void searchGeoCode(final ControleUnitarioMarker marker) {
		new Geocoder().getLocations(marker.getLatLng(), new LocationCallback() {
			@Override
			public void onSuccess(JsArray<Placemark> locations) {
				GWT.log("Recebendo as locations...", null);
				marker.setJsArray(locations);
				fillGeoCode(locations.get(0).getAddress());
			}

			@Override
			public void onFailure(int statusCode) {
				GWT.log("Falha no geocoding: " + statusCode, null);
				fillGeoCode("Não foi possível capturar o endereço.");
			}
		});
	}

	protected void fillGeoCode(String message) {
		geoCodeLabel.setText(message);
	}

	class ChangePontoClickHandler implements ClickHandler {

		private final ControleUnitarioMarker marker;

		public ChangePontoClickHandler(ControleUnitarioMarker controleUnitarioPoint) {
			this.marker = controleUnitarioPoint;
		}

		@Override
		public void onClick(ClickEvent event) {
			map.panTo(marker.getLatLng());
			showInfoWindow(marker);
		}

	}
}
